package com.xjtu.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjtu.project.common.utls.SessionUtils;
import com.xjtu.project.common.utls.SessionUtilsUser;
import com.xjtu.project.constant.OrderStatusConstants;
import com.xjtu.project.mapper.*;
import com.xjtu.project.model.domain.*;
import com.xjtu.project.model.dto.OrderRejectionDTO;
import com.xjtu.project.model.dto.OrderSubmitDTO;
import com.xjtu.project.model.dto.OrdersPageQueryDTO;
import com.xjtu.project.model.dto.PageDTO;
import com.xjtu.project.model.vo.OrderSubmitVO;
import com.xjtu.project.model.vo.OrdersVO;
import com.xjtu.project.service.OrdersService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
* @author 86185
* @description 针对表【orders】的数据库操作Service实现
* @createDate 2025-07-04 18:25:18
*/
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders>
    implements OrdersService {

    private final OrdersMapper ordersMapper;
    private final AddressMapper addressMapper;
    private final CartMapper cartMapper;
    private final OrderDetailMapper orderDetailMapper;
    private final UserMapper userMapper;

    public OrdersServiceImpl(OrdersMapper ordersMapper, AddressMapper addressMapper, CartMapper cartMapper, OrderDetailMapper orderDetailMapper, UserMapper userMapper) {
        this.ordersMapper = ordersMapper;
        this.addressMapper = addressMapper;
        this.cartMapper = cartMapper;
        this.orderDetailMapper = orderDetailMapper;
        this.userMapper = userMapper;
    }

    @Override
    public void cancel(OrderRejectionDTO orderRejectionDTO) {
        //直接修改订单状态为已取消，并且把拒绝原因保存
        lambdaUpdate().eq(Orders::getId, orderRejectionDTO.getId()).set(Orders::getCancelReason, orderRejectionDTO.getRejectionReason()).set(Orders::getStatus, OrderStatusConstants.CANCELED).update();
    }

    @Override
    public void complete(Integer id) {
        lambdaUpdate().eq(Orders::getId, id).set(Orders::getStatus, OrderStatusConstants.SHIPPED).update();
    }

    @Override
    public Page<Orders> conditionSearch(OrdersPageQueryDTO ordersPageQuery) {
        Page<Orders> page = new Page<>(ordersPageQuery.getPage(), ordersPageQuery.getPageSize());
        Page<Orders> p = lambdaQuery().eq(ordersPageQuery.getStatus()!=null,Orders::getStatus, ordersPageQuery.getStatus()).ge(ordersPageQuery.getBeginTime()!=null,Orders::getOrderTime, ordersPageQuery.getBeginTime()).le(ordersPageQuery.getEndTime()!=null,Orders::getOrderTime, ordersPageQuery.getEndTime()).page(page);
        //TODO 这里是否需要返回订单详细信息需要考究前端页面的搭建，就是具体买了什么商品
        return p;
    }

    @Override
    public PageDTO<OrdersVO> getMyOrders(OrdersPageQueryDTO ordersPageQuery) {
        ordersPageQuery.setPage((ordersPageQuery.getPage()-1)*ordersPageQuery.getPageSize());
        List<OrdersVO> p=ordersMapper.getMyOrders(ordersPageQuery,  SessionUtilsUser.getCurrentUserInfo().getId());
        return new PageDTO<OrdersVO>(ordersMapper.getTotalCount(ordersPageQuery.getStatus()), ordersPageQuery.getPageSize(),p);
    }

    @Override
    public void cancelById(Integer id) {
        lambdaUpdate().eq(Orders::getId, id).set(Orders::getStatus, OrderStatusConstants.CANCELED).update();
    }

    @Override
    @Transactional
    public OrderSubmitVO submit(OrderSubmitDTO submitDTO) {
        //构建订单 前端传过来金额，备注，地址id
        Orders orders = new Orders();
        orders.setUserId(SessionUtilsUser.getCurrentUserInfo().getId());
        BeanUtils.copyProperties(submitDTO, orders);
        orders.setStatus(OrderStatusConstants.PENDING_PAYMENT);
        //生成订单号
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setOrderTime(LocalDateTime.now());
        //根据addressId查地址簿
        Address address = addressMapper.selectById(submitDTO.getAddressId());
        orders.setAddress(address.getDetail());
        orders.setConsignee(address.getConsignee());
        orders.setPhone(address.getPhone());
        ordersMapper.add(orders);
        Integer id=orders.getId();
        //查询购物车然后把购物车信息加入到订单明细表中并删除购物车
        LambdaQueryWrapper<Cart> cartQueryWrapper = new LambdaQueryWrapper<>();
        cartQueryWrapper.eq(Cart::getUserId, SessionUtilsUser.getCurrentUserInfo().getId());
        List<Cart> cartList = cartMapper.selectList(cartQueryWrapper);
        for(Cart cart:cartList){
            OrderDetail orderDetail=OrderDetail.builder()
                    .orderId(id)
                    .name(cart.getName())
                    .number(cart.getNumber())
                    .amount(cart.getAmount())
                    .image(cart.getImage())
                    .shoeId(cart.getShoeId())
                    .size(cart.getSize())
                    .build();
            //插入订单明细表
            orderDetailMapper.insert(orderDetail);
        }
        //删除所有该用户id的购物车
        cartMapper.delete(cartQueryWrapper);
        return OrderSubmitVO.builder()
                .id(id)
                .number(orders.getNumber())
                .amount(orders.getAmount())
                .OrderTime(orders.getOrderTime())
                .build();
    }

    @Override
    @Transactional
    public void pay(String orderNumber) {
        Orders one = lambdaQuery().eq(Orders::getNumber, orderNumber).one();
        //扣减用户余额 如果用户余额不足则抛出异常并且回滚事务
        if(one.getAmount().compareTo(SessionUtilsUser.getCurrentUserInfo().getBalance())>0){
            throw new RuntimeException("余额不足");
        }
        lambdaUpdate().eq(Orders::getNumber, orderNumber).set(Orders::getStatus, OrderStatusConstants.PAID_AND_WAITING_FOR_SHIPMENT).update();
        //扣减余额  SessionUtilsUser.getCurrentUserInfo().getBalance().subtract(one.getAmount())
        LambdaUpdateWrapper<User> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(User::getId, SessionUtilsUser.getCurrentUserInfo().getId()).set(User::getBalance, SessionUtilsUser.getCurrentUserInfo().getBalance().subtract(one.getAmount()));
        userMapper.update(queryWrapper);
    }
}




